﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using KewlStuff.Misc;
using MovieBuddy.Controllers;
using MovieBuddy.Dialogs;
using MovieBuddy.Events;
using MovieBuddy.Helpers;
using MovieBuddy.Properties;
using MovieBuddy.Views;
using MovieBuddy.Views.TriViews;
using MovieModel.Common;
using MovieModel.FileSystem;
using MovieModel.Model;
using MovieModel.Model.Common;
using MovieModel.Search;

namespace MovieBuddy
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow
    {
        private static readonly Brush ActiveBrush = Brushes.DeepSkyBlue;
        private readonly IDictionary<Button, IMovieBuddyViewController<UserControl>> buttonsToViews;
        private Button currentViewSelection;  
        private readonly Manager manager;
        private MovieDetector detector;
        //private readonly TaskbarIcon notifyIcon = new TaskbarIcon();

        public MainWindow()
        {
            FormSizeSaver.RegisterForm(this, () => Settings.Default.MainWindowSettings,
                                       s =>
                                       {
                                           Settings.Default.MainWindowSettings = s;
                                           Settings.Default.Save();
                                       });
            try
            {
                InitializeComponent();
                string dataFolder = Settings.Default.DataFolder;
                DirectoryInfo dir;
                if (string.IsNullOrEmpty(dataFolder))
                {
                    string applicationDataFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
                    dir = new DirectoryInfo(applicationDataFolder + "/MovieBuddy");
                }
                else
                {
                    dir = new DirectoryInfo(dataFolder);
                }
                
                manager = new FileSystemManager(dir);

                if (manager.IsStorageReadyForInitialization()) manager.InitializeStorage();
                manager.Load(new ProgressWatcher());
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message +
                                ".   If a file is missing or corrupted, either recover it or remove the entire directory to start from scratch.\n\n" +
                                e.StackTrace);
                Environment.Exit(1);
            }

            movieView1.Manager = manager;

            PlaylistDialog.Instance.IsVisibleChanged +=
                (s, e) => playListBut.Foreground = PlaylistDialog.Instance.IsVisible ? ActiveBrush : Brushes.Black;

            buttonsToViews = new Dictionary<Button, IMovieBuddyViewController<UserControl>>
            {
                {moviesButton, new MovieViewController(manager, movieView1)},
                {tagsButton, new TagView(manager)},
                {peopleButton, new PeopleView(manager)}
            };

            foreach (var viewButton in buttonsToViews.Keys)
            {
                var viewButton2 = viewButton;
                viewButton2.Click += (sender, e) => ViewButtonClicked(viewButton2);
            }

            ViewButtonClicked(moviesButton);
            detector = new MovieDetector(manager);
            detector.DetectVideoFolder = Settings.Default.NewMovieFinderFolder;
            Closing += (sender, e) => detector.Shutdown();

            manager.MovieRemoved += MovieRemoved;
        }

        void MovieRemoved(object sender, ItemRemovedEventArgs<Movie> e)
        {
            PlaylistDialog.Instance.RemoveMovie(e.RemovedItem);
        }

        void ViewButtonClicked(Button viewSelection)
        {
            if (currentViewSelection != null)
            {
// ReSharper disable once PossibleUnintendedReferenceComparison
                if (viewSelection == currentViewSelection) return;

                currentViewSelection.Foreground = Brushes.Black;
            }

            viewSelection.Foreground = ActiveBrush;
            viewPanel.Children.Clear();
            viewPanel.Children.Add(buttonsToViews[viewSelection].Control);
            currentViewSelection = viewSelection;
            ApplyCurrentSearchToCurrentView();
        }

        private void ViewButtonClickedHandler(object sender, RoutedEventArgs e)
        {

        }

        private void LoadedHandler(object sender, RoutedEventArgs e)
        {

        }

        private void NewMovieButtonClick(object sender, RoutedEventArgs e)
        {
            var dialog = new NewMovieDialog(manager);
            dialog.Show();
        }

        private void AboutClicked(object sender, RoutedEventArgs e)
        {
            var dialog = new AboutDialog(manager);
            dialog.ShowDialog();
        }

        private void SearchTextChanged(object sender, TextChangedEventArgs e)
        {
            ApplyCurrentSearchToCurrentView();
        }

        private void ApplyCurrentSearchToCurrentView()
        {
            if (currentViewSelection != null)
                buttonsToViews[currentViewSelection].InvokeSearchChanged(new SearchEventArgs { NewSearchValue = ParseSearch() });
        }

        private SearchQuery ParseSearch()
        {
            string text = searchBox.Text;
            if (string.IsNullOrEmpty(text)) return new SearchQuery();
            return new SearchQuery {Free = new[] {text}};
        }

        private void MediaPlayersMenuClick(object sender, RoutedEventArgs e)
        {
            var dialog = new MediaPlayerSetup();
            dialog.ShowDialog();
        }

        private void ClosingHandler(object sender, System.ComponentModel.CancelEventArgs e)
        {
            PlaylistDialog.Instance.RealClose();
        }

        private void PlayListButHandler(object sender, RoutedEventArgs e)
        {
            var dialog = PlaylistDialog.Instance;
            if (dialog.IsVisible && dialog.WindowState == WindowState.Minimized)
            {
                dialog.WindowState = WindowState.Normal;
            }
            else if (dialog.IsVisible)
            {
                dialog.Hide();
            }
            else
            {
                dialog.Show();
                if (dialog.Visibility == Visibility.Collapsed)
                {
                    dialog.Visibility = Visibility.Visible;
                }
            }
        }

        private void OptionsClick(object sender, RoutedEventArgs e)
        {
            new OptionsDialogController(detector).Execute();
        }
    }
}
